OBJECTIF 3 : Accessibilité avec R et Open Street Map

AFROMPA’R Bouaké 2025

Auteur·rice

Claude Grasland & Bamba Vakaramoko

Date de publication

2025-03-28

Reprenant un cours dispensé lors de l’école d’été CIST 2023 au Bénin par C. Grasland et B. Vakaramoko et intitulé Distance et accessibilité, nous voudrions montrer lors de l’école d’été Afromap’R 2025 quelques exemples d’utilisation de la base de données OSRM et du package R correspondant pour effectuer des calculs de distance routière ou de distance-temps.

Les mesures de distance sont intéressantes en elle-même pour comparer les régions les plus accessibles ou les moins accessibles d’un territoire. Mais elles sont également utiles comme variables explicatives d’autres phénomènes de nature sociale ou économique. On peut par exemple mettre en rapport la distance à une capitale nationale ou un chef-lieu de région avec le niveau de développement d’une commune.

(1) LE PROJET OSRM

Le projet OSRM (Open SOurce Routing Machine) est un service de routage utilisant les données d’OpenStreetMap (OSM). Le package permet de calculer des routes, des matrices de distances, des isochrones en utilisant s’appuyant sur le réseau routier d’OSM. Il est accessible en ligne sur le site web suivant

https://project-osrm.org/

Le package R OSRM est une interface créée par Timothée Giraud, Robin Cura, Matthieu Viry et Robin Lovelace qui permet d’accéder à l’API OSRM depuis un programme R et ainsi d’effectuer automatiquement les calculs précédents. Il est accessible sur le CRAN et possède une documentation avec des exemples :

https://cran.r-project.org/web/packages/osrm/index.html

La dernière version d’OSRM a fait l’objet de révisions importantes par Timothée Giraud et qui a publié récemment un article à ce sujet dans JOSS qui est la revue de référence pour les package R.

  • Giraud, Timothée. 2022. “osrm: Interface Between R and the OpenStreetMap-Based Routing Service OSRM.” Journal of Open Source Software 7 (78): 4574. https://doi.org/10.21105/joss.04574.

L’objectif de l’exercice proposé lors de l’école d’été CIST2023 était d’essayer d’appliquer ce package ORSM au calcul des distances entre les chefs-lieux des 14 districts de Côte d’Ivoire, afin de vérifier si les résultats obtenus sont approximativement justes et ne comportent pas trop d’erreur. Il est en effet possible que l’analyse souffre de problèmes lorsque la couverture OSM n’est pas complète ou de qualité insuffisante.

(2) PREPARATION DES DONNEES

Données géométriques

Nous utiliserons trois fonds de cartes de type shapefile (enregistrés au format sf de R dans des fichiers de type .RDS) qui servent uniquement ici à repérer les positions des points ou à cartographier les résultats des analyses. Il s’agit :

  • du contour des 14 districts (source : OCHA)
  • du contour des 33 régions (source : OCHA)
  • des routes principales (source : OSM & OCHA)

Après chargement, on projette les fonds en EPSG 2043 pour avoir des coordonnées en kilomètres adaptées à la Côte d’Ivoire.

Code
# Contour du pays
map_state<-readRDS(file ="data/exo_access/CIV.RDS")
map_state_proj<-st_transform(map_state, crs = 2043)

# Districts
map_districts<-readRDS(file = "data/exo_access/CIV_DISTRICTS.RDS")
map_districts_proj<-st_transform(map_districts, crs = 2043)

# Regions
map_regions<-readRDS(file = "data/exo_access/CIV_REGIONS.RDS")
map_regions_proj<-st_transform(map_regions, crs = 2043)

# Routes (sélection des niveaux 1 et 2)
map_roads<-readRDS(file = "data/exo_access/CIV_ROADS.RDS") %>% filter(highway !="tertiary")
map_roads$niveau <-as.factor(map_roads$highway)
levels(map_roads$niveau)<-c("Autoroute","niveau 1", "niveau 2", "niveau 1")
map_roads$size<-4-as.numeric(map_roads$niveau)
map_roads<-map_roads %>% arrange(size)
map_roads_proj<-st_transform(map_roads, crs = 2043)

On peut en proposer une visualisation statique à l’aide du package mapsf :

Code
mf_theme(x = "agolalight")
mf_map(map_regions_proj,col="gray90",border="gray50",lwd=0.5)

mf_map(map_districts_proj,
       col=NA,
       border="black",
       lwd=2,add=T)

mf_map(map_roads_proj,
       type = "typo",
       var = "niveau",
       lwd= map_roads_proj$size,
       pal=c("red","orange","yellow"),
       add=T,
       leg_title = "Niveau des routes")

mf_label(map_districts_proj,
         var = "DIS_NOM",
         col = "blue",cex = 0.5)

mf_layout(title = "Le réseau routier de Côte d'Ivoire (source : OSM)",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = T)

Position des centroïdes des districts

Le calcul du centroïde des régions ou des districts est possible dans R avec la fonction st_centroid() du package sf. Il conduit à placer des points à un emplacement différent de celui des chef-lieux administratifs puisque ces derniers ne sont pas forcément situé au centre géométrique de leur unité administrative. Du coup les points correspondant aux centroïdes risquent d’être situés à l’écart du réseau routier ce qui va conduire à des erreurs de calcul lorsqu’on voudra estimer les distances. Par exemple, le centroïde du district de Woroba ne se situe pas sur une route principale ou même secondaire.Quand au centroïde du district de la vallée du Bandama, il est bien sur une route mais très au nord du chef-lieu de Bouaké qui est un véritable carrefour routier vers l’ensemble du pays.

Code
map_districts_ctr <- st_centroid(map_districts,of_largest_polygon = T, quiet=T)
map_districts_ctr_proj <- st_transform(map_districts_ctr, crs = 2043)

mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=2)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_ctr_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_ctr_proj,
         var = "DIS_NOM",
         col = "black",cex = 0.5,overlap = F)


mf_layout(title = "Position des centroïdes des districts de Côte d'Ivoire",
          credits ="Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = T)

Importation ou saisie des coordonnées des chefs-lieux de district

Pour obtenir des distances plus pertinentes, nous devons donc importer les coordonnées de longitude et de latitude des chef-lieux de districts entre lesquelles on souhaite mesurer des distances routières. Nous disposons pour cela de deux solutions :

  • Utiliser Google Maps ou Open Street Map pour repérer un point central dans les villes et en extraire les coordonnées. On choisira de préférence un point situé sur une route principale ou mieux encore un carrefour routier du centre-ville. Ainsi à Abidjan, on peut choisir le point situé Boulevard de la République face au palais présidentiel dont les coordonnées sont 5.3274 de latitude Nord et -4.0204 de longitude. Il est essentiel de disposer de coordonnées non projetées (EPSG 4326) pour pouvoir ensuite effectuer les calculs de distance.

  • Utiliser la base Africapolis qui fournit pour chaque agglomération les coordonnées de latitude et longitude du centroïde de la zone bâtie correspondant à l’extension spatiale de la ville. On ne va pas nécessairement sur un bâtiment remarquable, mais comme on se trouve à l’intérieur de la ville, il y a peu de chances de tomber dans une zone éloignée d’une route et l’erreur de calcul sera faible, surtout dans le cas des petites villes. Cette solution donne de bons résultats dans le cas de la Côte d’Ivoir où nous avons juste été obligé de corriger le point central retenu pour Abidjan.

Code
coo <-read.table(file = "data/exo_access/DIS_CHEF.csv", header=T, sep=";", dec=",") 
kable(coo,caption = "Coordonnées des chefs lieux de districts de Côte d'Ivoire")
Coordonnées des chefs lieux de districts de Côte d’Ivoire
DIS_CODE DIS_NOM DIS_CTR DIS_CTR_LON DIS_CTR_LAT
CI.CM Comoé Abengourou -3.49700 6.74000
CI.AB Abidjan Abidjan -4.02044 5.32374
CI.ZZ Zanzan Bondoukou -2.80300 8.03900
CI.VB Vallée du Bandama Bouaké -5.05000 7.69800
CI.LG Lagunes Dabou -4.37800 5.32000
CI.SM Sassandra-Marahoué Daloa -6.45500 6.87600
CI.LC Lacs Dimbokro -4.70700 6.65300
CI.GD Gôh-Djiboua Gagnoa -5.95900 6.13300
CI.SV Savanes Korhogo -5.63100 9.46200
CI.MG Montagnes Man -7.54800 7.40300
CI.DN Denguélé Odienné -7.56400 9.50300
CI.BS Bas-Sassandra San-Pédro -6.67000 4.75600
CI.WR Woroba Séguéla -6.67300 7.96300
CI.YM Yamoussoukro Yamoussoukro -5.26300 6.80700

A la différence des centroïdes,les chefs lieux de régions se superposent parfaitement sur le réseau routier dont ils constituent logiquement les principaux carrefours :

Code
map_districts_chef <- st_as_sf(coo, coords = c("DIS_CTR_LON","DIS_CTR_LAT"))
st_crs(map_districts_chef)<-4326
map_districts_chef_proj <- st_transform(map_districts_chef, crs = 2043)


mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=2)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Position des villes chef-lieux des districts de Côte d'Ivoire",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = T)

Sauvegarde des fichiers

Nous sauvegardons les nouveaux fichiers créés au cours de cette étape sous deux formes différentes : en coordonnées latitude longitude (EPSG 4326) et en coordonnées projetées (EPSG 2043).

Code
saveRDS(map_districts_ctr,"data/exo_access/CIV_DISTRICTS_CTR_4326.RDS")
saveRDS(map_districts_ctr_proj,"CIV/CIV_DISTRICTS_CTR_2043.RDS")

saveRDS(map_districts_chef,"data/exo_access/CIV_DISTRICTS_CHEF_4326.RDS")
saveRDS(map_districts_chef_proj,"data/exo_access/CIV_DISTRICTS_CHEF_2043.RDS")

saveRDS(map_roads,"data/exo_access/CIV_ROADS_4326.RDS")
saveRDS(map_roads_proj,"data/exo_access/CIV_ROADS_2043.RDS")

(3) CALCUL DE MATRICES DE DISTANCE

Calcul des distances à vol d’oiseau

Le calcul des distances à vol d’oiseau (à la surface de la Terre) s’effectue très facilement à l’aide de la fonction st_distance() du package sf. Il faut juste faire attention à bientransformer le tableau obtenu en matrice avec la fonction class() puis à rajouter les noms de lignes et de colonnes.

Code
dist_eu<-as.matrix(st_distance(map_districts_chef))/1000
class(dist_eu)<-"matrix"
row.names(dist_eu)<-map_districts$DIS_CTR
colnames(dist_eu)<-substr(map_districts$DIS_CTR,1,3)
kable(dist_eu, digits=0, caption="Distance à vol d'oiseau entre chefs-lieux de districts de Côte d'Ivoire")
Distance à vol d’oiseau entre chefs-lieux de districts de Côte d’Ivoire
Abi San Abe Odi Gag Dim Dab Man Dal Kor Bou Ség Yam Bon
Abidjan 0 168 163 202 186 327 134 280 383 453 543 415 376 195
San-Pédro 168 0 331 287 40 320 166 233 493 453 607 300 415 215
Abengourou 163 331 0 250 349 423 260 408 349 528 548 562 426 304
Odienné 202 287 250 0 275 180 122 201 206 277 342 373 181 102
Gagnoa 186 40 349 275 0 288 153 197 481 420 583 262 388 192
Dimbokro 327 320 423 180 288 0 195 99 302 134 317 237 123 132
Dabou 134 166 260 122 153 195 0 150 328 324 446 303 261 64
Man 280 233 408 201 197 99 150 0 372 225 414 172 218 107
Daloa 383 493 349 206 481 302 328 372 0 311 212 536 202 298
Korhogo 453 453 528 277 420 134 324 225 311 0 234 310 115 261
Bouaké 543 607 548 342 583 317 446 414 212 234 0 537 197 392
Séguéla 415 300 562 373 262 237 303 172 536 310 537 0 357 276
Yamoussoukro 376 415 426 181 388 123 261 218 202 115 197 357 0 202
Bondoukou 195 215 304 102 192 132 64 107 298 261 392 276 202 0

Calcul de matrices de distance et temps routier avec osrmTable()

La fonction demande les coordonnées de latitue et longitude des lieux pour lesquels on veut calculer les distances routières. On peut les fournir via un tableau (data.frame) ou via un objet de type spatial feature (sf) à condition que ce dernier soit en projection ESPG 4326 (c’est-à-dire non projeté). Voyons ici le premier cas à titre d’exemple :

On prépare un data.frame ne contenant que les coordonnées de longitude (en première colonne) et latitude (en deuxième colonne). Le nom des colonnes n’a pas d’importance mais il faut qu’il y en ait exactement deux et que la première corresponde bien aux longitudes et la seconde aux latitudes (en degrés décimaux). Il est en revanche important d’ajouter des noms de lignes au tableau pour pouvoir les retouver sur les marges de la matrice de distance.

Code
dis_chef<-read.table("data/exo_access/DIS_CHEF.csv", header=T, sep=";", dec=",")
coo<-dis_chef[,4:5]
row.names(coo)<-dis_chef$DIS_CTR
kable(coo,caption = "Fichier de coordonnées pour osrm (type data.frame ou matrix)")
Fichier de coordonnées pour osrm (type data.frame ou matrix)
DIS_CTR_LON DIS_CTR_LAT
Abengourou -3.49700 6.74000
Abidjan -4.02044 5.32374
Bondoukou -2.80300 8.03900
Bouaké -5.05000 7.69800
Dabou -4.37800 5.32000
Daloa -6.45500 6.87600
Dimbokro -4.70700 6.65300
Gagnoa -5.95900 6.13300
Korhogo -5.63100 9.46200
Man -7.54800 7.40300
Odienné -7.56400 9.50300
San-Pédro -6.67000 4.75600
Séguéla -6.67300 7.96300
Yamoussoukro -5.26300 6.80700

On peut alors effectuer le calcul de la matrice de distance routière soit en temps (“duration”), soit en kilomètre (“distance”) soit les deux à la fois (solution la plus simple). On récupère une liste qui comporte les deux matrices de distance ainsi que les coordonnées d’origine et de destination des lieux entr lesquels on a calculé les distances. Les temps routiers sont en minutes et les distances routières en mètres.

Code
dist <- osrmTable(coo, measure = c("duration", "distance"))

On procède ensuite à l’extraction des résultats sous la forme de matrices que l’on peut exprimer dans une autre unité de mesure (par exemple convertir les mètres en kilomètres). On en profite pour les symétriser car il peut arriver que la distance soit légèrement plus grande dans une des deux directions

Code
dist_km <- as.matrix(dist$distances)/1000
dist_km<-(dist_km+t(dist_km))/2
kable(dist_km, 
      caption="Distance routière entre chefs-lieux de districts de Côte d'Ivoire (en km)", 
      digits=0,
      col.names = substr(colnames(dist_km),1,3))
Distance routière entre chefs-lieux de districts de Côte d’Ivoire (en km)
Abe Abi Bon Bou Dab Dal Dim Gag Kor Man Odi San Ség Yam
Abengourou 0 205 196 291 235 385 161 324 506 571 738 523 510 242
Abidjan 205 0 398 347 47 378 236 273 563 564 795 334 503 235
Bondoukou 196 398 0 405 429 578 355 517 521 765 753 716 596 435
Bouaké 291 347 405 0 331 247 193 250 222 329 454 480 193 113
Dabou 235 47 429 331 0 361 220 238 547 547 778 288 486 218
Daloa 385 378 578 247 361 0 224 137 463 188 374 266 129 144
Dimbokro 161 236 355 193 220 224 0 163 410 410 641 391 349 81
Gagnoa 324 273 517 250 238 137 163 0 467 275 536 231 264 141
Korhogo 506 563 521 222 547 463 410 467 0 431 233 697 294 330
Man 571 564 765 329 547 188 410 275 431 0 264 404 136 330
Odienné 738 795 753 454 778 374 641 536 233 264 0 666 246 561
San-Pédro 523 334 716 480 288 266 391 231 697 404 666 0 394 389
Séguéla 510 503 596 193 486 129 349 264 294 136 246 394 0 269
Yamoussoukro 242 235 435 113 218 144 81 141 330 330 561 389 269 0
Code
dist_mn <- as.matrix(dist$durations)
dist_mn<-(dist_mn+t(dist_mn))/2
kable(dist_mn, 
      caption="Temps routier entre chefs-lieux de districts de Côte d'Ivoire (en minutes)", 
      digits=0,
      col.names = substr(colnames(dist_km),1,3))
Temps routier entre chefs-lieux de districts de Côte d’Ivoire (en minutes)
Abe Abi Bon Bou Dab Dal Dim Gag Kor Man Odi San Ség Yam
Abengourou 0 194 191 296 222 364 159 311 459 555 672 488 478 227
Abidjan 194 0 381 251 48 302 174 235 413 493 626 314 416 165
Bondoukou 191 381 0 409 408 550 346 498 494 742 708 675 634 414
Bouaké 296 251 409 0 260 216 156 228 187 400 400 435 246 87
Dabou 222 48 408 260 0 312 184 241 423 503 636 269 426 175
Daloa 364 302 550 216 312 0 207 137 379 195 399 244 121 138
Dimbokro 159 174 346 156 184 207 0 155 318 398 531 358 321 70
Gagnoa 311 235 498 228 241 137 155 0 391 286 526 211 254 146
Korhogo 459 413 494 187 423 379 318 391 0 428 216 597 273 250
Man 555 493 742 400 503 195 398 286 428 0 246 393 156 330
Odienné 672 626 708 400 636 399 531 526 216 246 0 633 279 463
San-Pédro 488 314 675 435 269 244 358 211 597 393 633 0 361 350
Séguéla 478 416 634 246 426 121 321 254 273 156 279 361 0 252
Yamoussoukro 227 165 414 87 175 138 70 146 250 330 463 350 252 0

Indices d’accessibilité

On peut résumer chacune de nos trois matrices à l’aide d’indices d’accessibilité.

Accessibilité moyenne

Code
dist_eu_mean <- apply(dist_eu,1,mean)
dist_km_mean <- apply(dist_km, 1,mean)
dist_mn_mean <- apply(dist_mn, 1,mean)
tab<-data.frame(dist_eu_mean, dist_km_mean,dist_mn_mean)
kable(tab, 
      caption = "Accessibilité moyenne des chefs-lieux de Côte d'Ivoire",
      col.names = c("Km à vol d'oiseau", "Km par la route", "Temps par la route"),
      digits=0)
Accessibilité moyenne des chefs-lieux de Côte d’Ivoire
Km à vol d’oiseau Km par la route Temps par la route
Abidjan 273 349 330
San-Pédro 288 348 287
Abengourou 350 476 461
Odienné 214 275 255
Gagnoa 272 337 293
Dimbokro 220 277 255
Dabou 208 274 241
Man 220 272 258
Daloa 320 406 345
Korhogo 289 373 366
Bouaké 384 503 453
Séguéla 331 413 381
Yamoussoukro 247 312 301
Bondoukou 196 249 219

Accessibilité moyenne pondérée

Code
dist_eu_mean <- apply(dist_eu,1,mean)
dist_km_mean <- apply(dist_km, 1,mean)
dist_mn_mean <- apply(dist_mn, 1,mean)
tab<-data.frame(dist_eu_mean, dist_km_mean,dist_mn_mean)
kable(tab, 
      caption = "Accessibilité moyenne des chefs-lieux de Côte d'Ivoire",
      col.names = c("Km à vol d'oiseau", "Km par la route", "Temps par la route"),
      digits=0)
Accessibilité moyenne des chefs-lieux de Côte d’Ivoire
Km à vol d’oiseau Km par la route Temps par la route
Abidjan 273 349 330
San-Pédro 288 348 287
Abengourou 350 476 461
Odienné 214 275 255
Gagnoa 272 337 293
Dimbokro 220 277 255
Dabou 208 274 241
Man 220 272 258
Daloa 320 406 345
Korhogo 289 373 366
Bouaké 384 503 453
Séguéla 331 413 381
Yamoussoukro 247 312 301
Bondoukou 196 249 219

Les matrices (quand elles ne sont pas trop grandes) sont des objets assez pratiques pour effectuer des calculs dans R et offrent des possibilités différentes de celles des data.frame. On peut par exemple diviser nos deux matrices l’une par l’autre afin de calculer la vitesse moyenne de circulation entre deux chefs-lieux :

Code
dist_ho <- dist_mn / 60
dist_km_ho <-dist_km / dist_ho
diag(dist_km_ho)<-NA
kable(dist_km_ho, 
      caption = "Vitesse de circulation routière entre chefs-lieux de Côte d'Ivoire (en km/h)", 
      digits = 0,
      col.names = substr(colnames(dist_km_ho),1,3))
Vitesse de circulation routière entre chefs-lieux de Côte d’Ivoire (en km/h)
Abe Abi Bon Bou Dab Dal Dim Gag Kor Man Odi San Ség Yam
Abengourou NA 63 61 59 64 64 61 62 66 62 66 64 64 64
Abidjan 63 NA 63 83 58 75 81 70 82 69 76 64 73 85
Bondoukou 61 63 NA 59 63 63 62 62 63 62 64 64 56 63
Bouaké 59 83 59 NA 76 68 75 66 71 49 68 66 47 78
Dabou 64 58 63 76 NA 70 72 59 78 65 73 64 69 75
Daloa 64 75 63 68 70 NA 65 60 73 58 56 66 64 62
Dimbokro 61 81 62 75 72 65 NA 63 77 62 72 65 65 69
Gagnoa 62 70 62 66 59 60 63 NA 72 58 61 66 62 58
Korhogo 66 82 63 71 78 73 77 72 NA 60 65 70 65 79
Man 62 69 62 49 65 58 62 58 60 NA 64 62 53 60
Odienné 66 76 64 68 73 56 72 61 65 64 NA 63 53 73
San-Pédro 64 64 64 66 64 66 65 66 70 62 63 NA 65 67
Séguéla 64 73 56 47 69 64 65 62 65 53 53 65 NA 64
Yamoussoukro 64 85 63 78 75 62 69 58 79 60 73 67 64 NA

On peut également effectuer des calculs rapides sur les lignes ou les colonnes de la matrice et ainsi produire les mesures d’accessibilité vues en cours. On se sert par exemple pour cela de la fonction apply() de R-base.

Code
dist_km_mean <- apply(dist_km, 1,mean)
dist_km_max <- apply(dist_km, 1,max)
dist_mn_mean <- apply(dist_mn, 1,mean)
dist_mn_max <- apply(dist_mn, 1,max)
tab<-data.frame(dist_km_mean,dist_km_max,dist_mn_mean,dist_mn_max)
tab$dist_km_ho_mean<-dist_km_mean/(dist_mn_mean/60)
kable(tab, 
      caption = "Indices d'accessibilité routière des chefs-lieux de Côte d'Ivoire",
      digits=0)
Indices d’accessibilité routière des chefs-lieux de Côte d’Ivoire
dist_km_mean dist_km_max dist_mn_mean dist_mn_max dist_km_ho_mean
Abengourou 349 738 330 672 64
Abidjan 348 795 287 626 73
Bondoukou 476 765 461 742 62
Bouaké 275 480 255 435 65
Dabou 337 778 293 636 69
Daloa 277 578 255 550 65
Dimbokro 274 641 241 531 68
Gagnoa 272 536 258 526 63
Korhogo 406 697 345 597 71
Man 373 765 366 742 61
Odienné 503 795 453 708 67
San-Pédro 413 716 381 675 65
Séguéla 312 596 301 634 62
Yamoussoukro 249 561 219 463 68
  • Accessiblité en km : d’après notre tableau (colonne dist_km_mean) c’est Yamoussoukro qui est la ville la plus accessible avec une distance moyenne de 247 km aux chefs-lieux de Côte d’Ivoire. Odienné est la ville la moins accessible avec une distance moyenne de 508 km.
  • Accessiblité en temps : d’après notre tableau (colonne dist_mn_mean) c’est toujours Yamoussoukro qui est la ville la plus accessible avec un temps moyen de 212 minutes (soit environ 3 heures et demi) pour rejoindre les chefs-lieux de Côte d’Ivoire. Bondioukou est la ville la moins accessible avec un temps moyen de 463 minutes (soit un peu moins de huit heures).
  • Equité en km : dans une logique d’équité (faire en sorte que le plus défavorisé soit le moins défavorisé possible), la ville la plus équitable est celle où la distance maximum est la plus faible. Il s’agit dans ce cas de Bouaké dont la distance maximale à un autre chef-lieu est de 473 km. Les localisation les moins équitables seraient Abidjan ou Odienné qui sont les deux centre les plus éloignés (794 km).
  • Equité en temps : dans une logique d’équité mesurée en temps, Bouaké demeure la meilleure option avec une durée de parcours maximale de 427 mn (soit environ 7 heures). Les localisations les moins équitables seraient désormais Bondoukou ou Odienné qui sont éloigénes de 750 mn (soit près de 13 heures).
  • Vitesse : dans une logique de vitesse de circulation (qui témoigne de la qualité des routes qui partent d’une ville), c’est Abidjan qui apparaît la mieux équipée puisque la vitesse moyenne pour rejoindre les autres villes y est de 74 km/h. La plus faible performance est pour Séguéla (61 km/h). La vitesse ne tient cependant pas compte des éventuels détours effectués par la route.

(4) CARTOGRAPHIE D’ISOCHRONES

Exemple de Bouaké

On commence par repérer les coordonnées les plus exactes possibles du marché de Bouaké en se servant par exemple de Google Maps. Puis on va utiliser soit la fonction osrmIsochrone(), soit la fonction osrmIsodistance() du package osrmpour générer des polygones correspondant aux points situés respectivement à une même distance en temps ou une même distance en kilomètres par la route.

Code
iso_time <- osrmIsochrone(loc = c(-5.02483,7.69714),
                                 breaks = c(0,30,60,90,120,150,180, 210, 240)
                                 )
iso_time$isomean=(iso_time$isomin+iso_time$isomax)/120
iso_time_proj<-st_transform(iso_time, crs=2043)


iso_dist <- osrmIsodistance(loc = c(-5.02483,7.69714),
                                 breaks = c(0,30000,60000,90000,120000,150000, 180000, 210000, 240000))
iso_dist$isomean=(iso_dist$isomin+iso_dist$isomax)/2000
iso_dist_proj<-st_transform(iso_dist, crs=2043)

On peut maintenant tracer deux cartes d’isolignes, l’une correspondant aux temps et l’autre aux distances :

Code
png("data/exo_access/bouake.png", width=1000, height=500)
par(mfrow=c(1,2))
### Distance kilométrique
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_dist_proj,
       type="choro",
       var="isomean",
       nbreaks=8,
       leg_title = "distance (km)",
       leg_val_rnd = 0,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance kilométrique ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            


#### Distance temps
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_time_proj,
       type="choro",
       var="isomean",
       breaks=c(0,0.501,1.001,1.5001,2.001,2.5001,3.001,3.5001,4.001),
   #    nbreaks=8,
       leg_title = "temps (heures)",
       leg_val_rnd = 1,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance temps ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            
dev.off()

  • Commentaire : La zone accessible en mois de 240 km recouvre l’essentiel de la partie centrale du pays et affiche une forme globalement circulaire en raison de la situation de carrefour de Bouaké. Mais la zone accessible en mois de 4 h est davantage allongé dans le sens Nord-Sud en raison de la présence d’autoroutes ou de voies rapides sur l’axe Abidjan-Yamoussoukro-Korhogo. Evidemment ces calculs théoriques ne tiennent pas compte des barrages et des “corps habillés” …

Exemple d’Abidjan

A titre de comparaison, on refait le même exercice pour Abidjan en prenant comme point de départ le Plateau.

Code
iso_time <- osrmIsochrone(loc = c(-4.02044,5.32374),
                                 breaks = c(0,30,60,90,120,150,180, 210, 240)
                                 )
iso_time$isomean=(iso_time$isomin+iso_time$isomax)/120
iso_time_proj<-st_transform(iso_time, crs=2043)


iso_dist <- osrmIsodistance(loc = c(-4.02044,5.32374),
                                 breaks = c(0,30000,60000,90000,120000,150000, 180000, 210000, 240000))
iso_dist$isomean=(iso_dist$isomin+iso_dist$isomax)/2000
iso_dist_proj<-st_transform(iso_dist, crs=2043)


png("data/exo_access/abidjan.png", width=1000, height=500)
par(mfrow=c(1,2))
### Distance kilométrique
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_dist_proj,
       type="choro",
       var="isomean",
       nbreaks=8,
       leg_title = "distance (km)",
       leg_val_rnd = 0,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance kilométrique ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            


#### Distance temps
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_time_proj,
       type="choro",
       var="isomean",
       breaks=c(0,0.501,1.001,1.5001,2.001,2.5001,3.001,3.5001,4.001),
   #    nbreaks=8,
       leg_title = "temps (heures)",
       leg_val_rnd = 1,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance temps ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            
dev.off()          

  • Commentaire : La zone accessible en moins de 240 km se limite au quart sud-ouest du pays et permet d’atteindre Yamoussoukro mais pas Bouaké. Par contre, si on raisonne en distance-temps, la zone accessible en moins de 4h s’élargit fortement en direction du Nord pour atteindre Bouaké grâce à l’autoroute.

Exemple d’Odienné

On prend maintenant le cas d’Odienné qui est l’une des villes les plus périphériques et les moins bien relié au reste du pays.

Code
iso_time <- osrmIsochrone(loc = c(-7.56400,9.50300),
                                 breaks = c(0,30,60,90,120,150,180, 210, 240)
                                 )
iso_time$isomean=(iso_time$isomin+iso_time$isomax)/120
iso_time_proj<-st_transform(iso_time, crs=2043)


iso_dist <- osrmIsodistance(loc = c(-7.56400,9.50300),
                                 breaks = c(0,30000,60000,90000,120000,150000, 180000, 210000, 240000))
iso_dist$isomean=(iso_dist$isomin+iso_dist$isomax)/2000
iso_dist_proj<-st_transform(iso_dist, crs=2043)


png("data/exo_access/odienne.png", width=1000, height=500)
par(mfrow=c(1,2))
### Distance kilométrique
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_dist_proj,
       type="choro",
       var="isomean",
       nbreaks=8,
       leg_title = "distance (km)",
       leg_val_rnd = 0,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance kilométrique ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            


#### Distance temps
mf_theme(x = "agolalight")

mf_map(map_districts_proj,
       col="gray90",
       border="gray50",
       lwd=1)


mf_map(iso_time_proj,
       type="choro",
       var="isomean",
       breaks=c(0,0.501,1.001,1.5001,2.001,2.5001,3.001,3.5001,4.001),
   #    nbreaks=8,
       leg_title = "temps (heures)",
       leg_val_rnd = 1,
      border=NA,
       add=T)

mf_map(map_districts_proj,
       col=NA,
       border="gray50",
       lwd=1,
       add=T)

mf_map(map_roads_proj,
       var = "niveau",
       lwd= map_roads_proj$size,
       col="yellow",
       add=T)

mf_map(map_districts_chef_proj,
       pch= 20,
       col="red",
       border="yellow",
       lwd=1,
       cex = 1.3,
       add=T)

mf_label(map_districts_chef_proj,
         var = "DIS_CTR",
         col = "black",cex = 0.5, overlap = F)


mf_layout(title = "Distance temps ",
          credits = "Grasland C. & Vakaramoko B., EE CIST 2023",
          frame = T,scale = T, arrow = F)
            
dev.off()            

  • Commentaire : la zone accessible en 240 km ou 4h est assez réduite à l’intérieur de la Côte d’Ivoire. Toutefois, le calcul effectué par OSRM ne se limite pas aux frontières du pays et indique une accessibilité possibles de territoires voisins situés en Guinée ou au Mali.

CONCLUSION

L’exercice a montré que les calculs de distances routières effectuées à l’aide d’Open Street Map fournissent d’assez bonnes approximations des distances kilométriques et des distances temps. Les calculs sont certes moins précis que ceux que l’on peut effectuer en temps réel à l’aide de fournisseurs privés tels que Google Map. Mais ils fournissent des résultats libres de droits à partir d’une base de donnée mise à jour régulièrement par les citoyens du pays.